package com.cehome.cloudbox.service;

import com.cehome.cloudbox.constans.ExtensionTaskProperties;
import com.cehome.cloudbox.constans.MsgConstants;
import com.cehome.cloudbox.doman.vo.ProDefExtemdInfo;
import com.cehome.cloudbox.doman.vo.ProcInstInfo;
import com.cehome.cloudbox.doman.vo.TaskInfo;
import com.cehome.cloudbox.entity.Inform;
import com.cehome.cloudbox.exception.BizException;
import com.cehome.cloudbox.flowalbe.FlowableReturnModel;
import com.cehome.cloudbox.flowalbe.FlowableTaskService;
import com.cehome.cloudbox.mapper.ProcDefExtendMapper;
import org.flowable.bpmn.model.ExtensionElement;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zfl
 */
@Service
public class ProcessIntanceLastService {

    @Autowired
    IProcDefExtendService procDefExtendService;

    @Autowired
    RuntimeService runtimeService;

    @Resource
    ProcDefExtendMapper procDefExtendMapper;

    @Autowired
    FlowableTaskService flowableTaskService;

    @Resource
    private IProcCommonService iProcCommonService;

    @Autowired
    TaskService taskService;



    /**
     * 获取所有流程定义
     * @param orgId
     * @param type
     * @return
     */
    public List<Object> getAllProc(String orgId,int type){
        return procDefExtendMapper.getAllProc( orgId, type);
    }

    /**
     * 3、发起流程
     * @param procInstInfo
     * @param infoUrl
     * @param title
     * @return
     */
    //流程启动后给流程赋值，不管是单签还是会签，第一个节点的单数都是huiqian
    //首先我要知道是哪个流程,infourl详情页面路径，title是流程发起标题，知会使用
    public String startProcess(ProcInstInfo procInstInfo,String infoUrl,String title){
        Map<String,Object> variables=new HashMap<String,Object>();
        if(null != procInstInfo.getChaosong()){
            variables.put("zhihui",procInstInfo.getChaosong());
        }
        //用于查询待办标题，就是申请标题
        variables.put("title",title);
        if(null == procInstInfo.getHuiqian() || procInstInfo.getHuiqian().size()<=0){
            throw new BizException("未选择下节点任务责任人");
        }
        variables.put("applyInfo",procInstInfo.getApplyInfo());
        //自定义参数入参
        Map<String,Object> custom = procInstInfo.getVariables();
        if(null!= custom && custom.size()>0){
            for (Map.Entry<String, Object> stringObjectEntry : custom.entrySet()) {
                variables.put(stringObjectEntry.getKey(),stringObjectEntry.getValue());
            }
        }
        variables.put("huiqian",procInstInfo.getHuiqian());
        Authentication.setAuthenticatedUserId(procInstInfo.getUserId());
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(procInstInfo.getProdefKey(),variables);
        if(null != procInstInfo.getChaosong() && procInstInfo.getChaosong().size()>0){
            //新增知会数据infoUrl为详情页面例如：http:url/instanceId
            for (String s : procInstInfo.getChaosong()) {
                Inform inform = new Inform();
                inform.setInfoUrl(infoUrl);
                inform.setInstanceId(processInstance.getId());
                inform.setTitle(title);
                inform.setUserId(s);
                //informService.insertNoExist(inform);
            }
        }
        //流程启动成功返回成功信息提示，自行修改
        return processInstance.getId();
    }

    /**
     * 4、获取任务待办
     * @param userId
     * @return
     */
    public List<Map<String,Object>> getInstanceTo(String userId){
        return procDefExtendMapper.getInstanceTo(userId);
    }

    /**
     * 4.1根据流程id获取对应流程中的参数,用来补充表单信息
     * @return
     */
    public Map<String,Object> getInstanceParamById(String procId){
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().
                includeProcessVariables().processInstanceId(procId).active().singleResult();
        return processInstance.getProcessVariables();
    }


    /**
     * 5、根据taskId获取下一节点的审批配置数据
     * @param taskId
     * @return
     */
    public FlowableReturnModel getByTaskId(String taskId){
        Task nowtask = flowableTaskService.getTaskByTaskId(taskId);
        //获取流程节点数据
        FlowElement flowElement = flowableTaskService.getNodeByTask(nowtask,"now");

        FlowElement flowElementNext = flowableTaskService.getNodeByTask(nowtask,"next");
        if("endEvent_1".equals(flowElementNext.getId())){
            return null;
        }
        //获取自定义的参数信息
        Map<String, List<ExtensionElement>> extensionElements = flowElement.getExtensionElements();
        //获取下节点的自定义参数设置
        FlowableReturnModel flowableReturnModel = getModel(flowElement.getId(),extensionElements);
        return flowableReturnModel;
    }

    /**
     *6、审批
     * @param procInstInfo
     * @return
     */
    public Object approveProcess(ProcInstInfo procInstInfo){
        //
        Map<String,Object> variables=new HashMap<String,Object>();
        if(null != procInstInfo.getChaosong()){
            variables.put("zhihui",procInstInfo.getChaosong());
        }
        variables.put("applyInfo",procInstInfo.getApplyInfo());
        //获取当前此用户的任务节点数据
        Task nowtask = flowableTaskService.getTaskByTaskId(procInstInfo.getTaskId());
        taskService.setVariable(nowtask.getId(), ExtensionTaskProperties.FLOWABLE_APPLY_DEFINITION_ID, nowtask.getTaskDefinitionKey());

        //获取流程节点数据
        FlowElement flowElement = flowableTaskService.getNodeByTask(nowtask,"now");

        FlowElement flowElementEnd = flowableTaskService.getNodeByTask(nowtask,"next");
        //审批之后就不能再撤回了，所以这里要修改
        variables.put( ExtensionTaskProperties.FLOWABLE_APPLY_DEFINITION_ID,"hasApprove");
        //获取自定义的参数信息
        Map<String, List<ExtensionElement>> extensionElements = flowElement.getExtensionElements();
        //获取下节点的自定义参数设置
        FlowableReturnModel flowableReturnModel = getModel(flowElement.getId(),extensionElements);
        //给下级节点复制审批人
        variables.put(flowableReturnModel.getAssignListName(),procInstInfo.getHuiqian());
        //自定义参数入参
        Map<String,Object> custom = procInstInfo.getVariables();
        if(null!= custom && custom.size()>0){
            for (Map.Entry<String, Object> stringObjectEntry : custom.entrySet()) {
                variables.put(stringObjectEntry.getKey(),stringObjectEntry.getValue());
            }
        }
        // 添加意见
        iProcCommonService.addTaskHandleComment(nowtask.getId(), nowtask.getProcessInstanceId(),nowtask.getName(), procInstInfo.getComment(), procInstInfo.getUserId());
        //完成当前节点审批，map入参可以自定义增加
        flowableTaskService.finishCurrentTaskByTaskId(nowtask,variables);
//        if(null != procInstInfo.getChaosong() && procInstInfo.getChaosong().size()>0){
//            //新增知会数据infoUrl为详情页面例如：http:url/instanceId
//            //新增知会数据infoUrl为详情页面例如：http:url/instanceId
//            for (String s : procInstInfo.getChaosong()) {
//                Inform inform = new Inform();
//                inform.setInfoUrl(infoUrl);
//                inform.setInstanceId(nowtask.getProcessInstanceId());
//                inform.setTitle(title);
//                inform.setUserId(s);
//                //informService.insertNoExist(inform);
//            }
//        }
        return "success";
    }

    public FlowableReturnModel getModel(String id,Map<String, List<ExtensionElement>> map){
        if(null == map || map.size()<=0){
            throw new BizException(MsgConstants.ERR_E099);
        }
        FlowableReturnModel flowableReturnModel = new FlowableReturnModel();
        ExtensionElement extensionElement = null;
        //获取下一参数节点的集合参数名称
        List<ExtensionElement> assignListNames = map.get(id+"nextParam");
        if(null!=assignListNames && assignListNames.size()>0){
            extensionElement = assignListNames.get(0);
            flowableReturnModel.setAssignListName(extensionElement.getElementText());
        }

       //获取指定的审批人
        List<ExtensionElement> roleApproves = map.get(id+"shenpi");
        if(null!=roleApproves && roleApproves.size()>0){
            extensionElement = roleApproves.get(0);
            flowableReturnModel.setShenpiStr(extensionElement.getElementText());
        }

        //获取下一审批是否是单选
        List<ExtensionElement> huiqs = map.get(id+"isHuiqian");
        if(null!=huiqs && huiqs.size()>0){
            extensionElement = huiqs.get(0);
            flowableReturnModel.setIsHuiqian(Boolean.valueOf(extensionElement.getElementText()));
        }


        //获取指定的知会人员
        List<ExtensionElement> persons = map.get(id+"zhihui");
        if(null!=persons && persons.size()>0){
            extensionElement = persons.get(0);
            flowableReturnModel.setZhihui(extensionElement.getElementText());
        }

        return flowableReturnModel;
    }
}
